package com.kinghood.productcenter.service.base.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kinghood.infrastructure.api.authority.SysLogModuleEnum;
import com.kinghood.infrastructure.api.authority.UserRemoteVo;
import com.kinghood.infrastructure.model.KingHoodException;
import com.kinghood.infrastructure.model.constant.CommonConstants;
import com.kinghood.infrastructure.model.enums.StatusEnum;
import com.kinghood.infrastructure.util.base.IdGenUtil;
import com.kinghood.infrastructure.util.UserUtil;
import com.kinghood.infrastructure.util.excel.EasyExcelUtil;
import com.kinghood.productcenter.common.api.authority.UserRemote;
import com.kinghood.productcenter.common.model.dao.base.BaseBrandDO;
import com.kinghood.infrastructure.model.dto.SortReqDTO;
import com.kinghood.infrastructure.model.dto.StatusReqDTO;
import com.kinghood.productcenter.common.model.dao.product.DownloadCenterDO;
import com.kinghood.productcenter.common.model.dao.product.ProductBaseDO;
import com.kinghood.productcenter.common.model.dto.base.BrandReqDTO;
import com.kinghood.productcenter.common.model.dto.base.ListBrandQueryDTO;
import com.kinghood.productcenter.common.model.excel.BrandExcel;
import com.kinghood.productcenter.common.model.vo.base.BrandSelectVO;
import com.kinghood.productcenter.common.model.vo.base.BrandVO;
import com.kinghood.productcenter.common.utils.UserNameUtil;
import com.kinghood.productcenter.dao.base.BaseBrandMapper;
import com.kinghood.productcenter.service.async.IAsyncHuaWeiYunService;
import com.kinghood.productcenter.service.base.IBaseBrandService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinghood.productcenter.service.product.IDownloadCenterService;
import com.kinghood.productcenter.service.product.IProductBaseService;
import com.kinghood.productcenter.service.product.handler.ProductBaseHandler;
import com.kinghood.sharding.model.BasePage;
import com.kinghood.sharding.model.KingHoodPageUtil;
import com.kinghood.sharding.model.KingPageResult;
import com.kinghood.sharding.model.PageResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 基础选项-品牌 服务实现类
 * </p>
 *
 * @author KingHood
 * @since 2023-12-20
 */
@Service
@Slf4j
public class BaseBrandServiceImpl extends ServiceImpl<BaseBrandMapper, BaseBrandDO> implements IBaseBrandService {

    @Value("${base.uploadPath}")
    private String uploadPath;
    @Resource
    private UserRemote userRemote;
    @Resource
    private IDownloadCenterService downloadCenterService;
    @Resource
    private IProductBaseService productBaseService;
    @Resource
    private IAsyncHuaWeiYunService asyncUploadHuaWeiYun;

    /**
     * 品牌列表
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/21
     */
    @Override
    public PageResponseVO listBrand(ListBrandQueryDTO param) {
        Page<BrandVO> result = this.baseMapper.listBrand(KingHoodPageUtil.getPage(param, param), param);

        Set<Long> userIdList = new HashSet<>();
        for (BrandVO record : result.getRecords()) {
            userIdList.add(record.getCreateUserId());
            userIdList.add(record.getUpdateUserId());
            record.setStatusTxt(StatusEnum.getNameByStatus(record.getStatus()));
        }
        userIdList.remove(null);
        if (!CollectionUtils.isEmpty(userIdList)) {
            Map<Long, UserRemoteVo> userMap = userRemote.getUserByIds(new ArrayList<Long>(userIdList));
            for (BrandVO record : result.getRecords()) {
                record.setCreateUserName(UserNameUtil.getName(record.getCreateUserId(), userMap));
                record.setUpdateUserName(UserNameUtil.getName(record.getUpdateUserId(), userMap));
            }
        }
        return KingPageResult.getResult(result);
    }

    /**
     * 获取所有品牌
     *
     * @author jp
     * @date 2024/01/03
     */
    @Override
    public List<BrandSelectVO> getAllBrand() {
        List<BrandSelectVO> result = this.baseMapper.getAllBrand();
        for (BrandSelectVO brand : result) {
            brand.setCodeName("["+brand.getBrandCode()+"]"+brand.getBrandName());
        }
        return result;
    }

    /**
     * 新增、修改
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/21
     */
    @Override
    public void addorUpdateBrand(BrandReqDTO param) {
        checkOnly(param);
        BaseBrandDO brand = new BaseBrandDO();
        LocalDateTime now = LocalDateTime.now();
        BeanUtils.copyProperties(param, brand);
        if (Objects.isNull(param.getId())) {
            brand.setId(IdGenUtil.get().nextId());
            brand.setCreateTime(now);
            brand.setCreateUserId(UserUtil.getUserId());
            brand.setUpdateTime(now);
            brand.setUpdateUserId(UserUtil.getUserId());
            this.save(brand);
        } else {
            brand.setUpdateTime(now);
            brand.setUpdateUserId(UserUtil.getUserId());
            this.updateById(brand);
        }
    }

    /**
     * 检查是否唯一
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/21
     */
    private void checkOnly(BrandReqDTO param){
        Long count = 0l;
        if (Objects.isNull(param.getId())) {
            count = this.lambdaQuery().eq(BaseBrandDO::getBrandCode, param.getBrandCode())
                    .eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
        } else {
            count = this.lambdaQuery().eq(BaseBrandDO::getBrandCode, param.getBrandCode())
                    .ne(BaseBrandDO::getId, param.getId())
                    .eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
        }
    }

    /**
     * 删除
     *
     * @param id 身份证件
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void delBrandById(Long id) {
        BaseBrandDO brand = this.getById(id);
        if (Objects.nonNull(brand) && !brand.getStatus().equals(CommonConstants.DISABLE)) {
            throw new KingHoodException(-1 , "只有停用状态的才可操作删除");
        }
        long count = productBaseService.lambdaQuery().eq(ProductBaseDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(ProductBaseDO::getBrandId, id)
                .count();
        if (count > 0) {
            throw new KingHoodException(-1, "存在关联商品，请移除后再删");
        }
        this.lambdaUpdate().set(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                .set(BaseBrandDO::getUpdateTime, LocalDateTime.now())
                .set(BaseBrandDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseBrandDO::getId, id)
                .eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 细节品牌
     *
     * @param id 身份证件
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public BrandVO detailBrand(Long id) {
        BrandVO result=new BrandVO();
        BaseBrandDO brand = this.lambdaQuery().eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(BaseBrandDO::getId, id)
                .one();
        if (Objects.nonNull(brand)) {
            BeanUtils.copyProperties(brand, result);
            return result;
        }
        return null;
    }

    /**
     * 更新品牌状态
     *
     * @param param 参数
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void updateBrandStatus(StatusReqDTO param) {
        this.lambdaUpdate().set(BaseBrandDO::getStatus, param.getStatus())
                .set(BaseBrandDO::getUpdateTime, LocalDateTime.now())
                .set(BaseBrandDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseBrandDO::getId, param.getId())
                .eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 更新品牌排序
     *
     * @param param 参数
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void updateBrandSort(SortReqDTO param) {
        this.lambdaUpdate().set(BaseBrandDO::getSort, param.getSort())
                .set(BaseBrandDO::getUpdateTime, LocalDateTime.now())
                .set(BaseBrandDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseBrandDO::getId, param.getId())
                .eq(BaseBrandDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }

    /**
     * 下载品牌
     *
     * @param param    参数
     * @param response 回答
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void downloadBrand(ListBrandQueryDTO param, HttpServletResponse response) {
        String fileName = StringUtils.isEmpty(param.getFileName()) ? "品牌数据" : param.getFileName();
        String sheetName = StringUtils.isEmpty(param.getSheetName()) ? "品牌" : param.getSheetName();

        if (Objects.isNull(param.getPage())) {
            param.setPage(new BasePage());
            param.getPage().setPageSize(99999);
        }
        PageResponseVO responseVO = listBrand(param);
        List<BrandVO> dataList = responseVO.getList();
        List<BrandExcel> result = new ArrayList<>();
        for (BrandVO goodsVO : dataList) {
            BrandExcel excel = new BrandExcel();
            BeanUtils.copyProperties(goodsVO, excel);
            result.add(excel);
        }
        // 保存到数据库
        LocalDateTime now = LocalDateTime.now();
        DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
        try {
            String showParam = "";
            if (!CollectionUtils.isEmpty(param.getDownloadField())) {
                showParam = String.join(",", param.getDownloadField());
            }
            String path = EasyExcelUtil.export(response, fileName, sheetName, result, BrandExcel.class,
                    showParam, uploadPath);
            File file = new File(path);
            downloadCenterDO.setId(IdGenUtil.getId())
                    .setFileName(file.getName())
                    .setModule(SysLogModuleEnum.PRODUCT_BRAND.getType())
                    .setType(2)
                    .setFileSize(ProductBaseHandler.getSizeName(file.length()))
                    .setUrl(path)
                    .setCreateTime(now)
                    .setUpdateTime(now)
                    .setCreateUserId(UserUtil.getUserId())
                    .setUpdateUserId(UserUtil.getUserId());
            downloadCenterService.save(downloadCenterDO);
            asyncUploadHuaWeiYun.uploadToHuaWeiYun(downloadCenterDO.getId(), file.getAbsolutePath());
        } catch (IOException e) {
            log.error("保存品牌异常：",e);
            throw new RuntimeException(e);
        }
    }
}
